home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
access
/
hddriver
/
driver
/
perform_io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
4KB
|
207 lines
/*
* Copyright 1987 Alan Kent
*
* Permission is granted to redistribute this code as long
* as this message is retained in the code and the code is
* not sold without written permission from the author.
*
* UUCP: {seismo,hplabs,mcvax,ukc,nttlab}!munnari!goanna.oz!ajk
* ACSnet: ajk@goanna.oz
* ARPA: munnari!goanna.oz!ajk@SEISMO.ARPA
*/
#include "hd.h"
void
perform_io ( ior )
struct IOExtHD *ior;
{
register struct IOStdReq *sior;
register int i;
UBYTE *buf;
struct hd_unit *unit;
struct posn posn;
int cmd;
LONG num_secs;
char *p;
sior = &ior->iohd_TD.iotd_Req;
unit = (struct hd_unit *) sior->io_Unit;
sior->io_Error = 0;
bad_error = 0;
cmd = sior->io_Command;
if ( cmd & TDF_EXTCOM ) {
if ( ior->iohd_TD.iotd_Count < CHANGE_COUNT ) {
sior->io_Error = TDERR_DiskChanged;
cmd = TD_LASTCOMM + 1;
}
else if ( ior->iohd_TD.iotd_SecLabel != NULL ) {
/* I didnt think theses were actually used! */
sior->io_Error = TDERR_NoSecHdr;
cmd = TD_LASTCOMM + 1;
}
}
switch ( cmd ) {
default :
if ( sior->io_Error == 0 )
sior->io_Error = IOERR_NOCMD;
break;
case ETD_MOTOR :
case TD_MOTOR :
sior->io_Actual = 1; /* motor always on - cannot be switched off */
break;
case TD_REMOVE :
/* cannot remove a harddisk, so not need to install interrupt */
/* thingo */
break;
case TD_CHANGENUM :
sior->io_Actual = CHANGE_COUNT;
break;
case TD_CHANGESTATE :
sior->io_Actual = 0;
break;
case TD_PROTSTATUS :
sior->io_Actual = 0;
break;
case ETD_CLEAR :
case CMD_CLEAR :
clear_all ();
break;
case ETD_UPDATE :
case CMD_UPDATE :
flush_all ();
if ( sior->io_Error == 0 )
sior->io_Error = bad_error;
break;
case ETD_READ :
case CMD_READ :
sior->io_Actual = 0;
if ( calc ( sior , &posn , &num_secs ) ) {
p = (char *) sior->io_Data;
while ( num_secs-- > 0 ) {
if ( posn.cylinder >= first.cylinders ) {
sior->io_Error = TDERR_SeekError;
break;
}
buf = read_cache ( &posn );
if ( bad_error != 0 || buf == NULL )
break;
copy_sector ( buf , p );
p += HD_SECTOR;
sior->io_Actual += HD_SECTOR;
next_posn ( &posn );
}
}
if ( sior->io_Error == 0 )
sior->io_Error = bad_error;
break;
case ETD_WRITE :
case CMD_WRITE :
sior->io_Actual = 0;
if ( calc ( sior , &posn , &num_secs ) ) {
p = (char *) sior->io_Data;
while ( num_secs-- > 0 ) {
if ( posn.cylinder >= first.cylinders ) {
sior->io_Error = TDERR_SeekError;
break;
}
write_cache ( &posn , p );
if ( bad_error != 0 )
break;
p += HD_SECTOR;
sior->io_Actual += HD_SECTOR;
next_posn ( &posn );
}
}
if ( sior->io_Error == 0 )
sior->io_Error = bad_error;
break;
case TD_SEEK :
if ( calc ( sior , &posn , &num_secs ) )
sior->io_Error = wd_seek ( &posn );
break;
case TD_FORMAT :
flush_all ();
clear_all ();
if ( calc ( sior , &posn , &num_secs ) ) {
if ( posn.sector != 0 ) {
sior->io_Error = TDERR_NotSpecified;
}
else {
p = (char *) sior->io_Data;
while ( num_secs-- > 0 ) {
if ( posn.cylinder >= first.cylinders ) {
sior->io_Error = TDERR_SeekError;
break;
}
if ( posn.sector == 0 ) {
sior->io_Error = wd_format_track ( &posn );
if ( sior->io_Error != 0 )
break;
}
write_sector ( &posn , p );
if ( bad_error != 0 ) {
sior->io_Error = bad_error;
break;
}
p += HD_SECTOR;
next_posn ( &posn );
if ( posn.sector == 0 )
p = (char *) sior->io_Data;
}
}
}
break;
case HD_PARK :
wd_park ();
break;
case HD_GETINFO :
ior->iohd_Info = first;
break;
}
/* if quick io, dont do a reply */
if ( ( sior->io_Flags & IOF_QUICK ) == 0 )
ReplyMsg ( ior );
}
next_posn ( posn )
register struct posn *posn;
{
posn->block++;
posn->sector++;
if ( posn->sector >= first.sectors ) {
posn->sector = 0;
posn->surface++;
if ( posn->surface >= first.heads ) {
posn->surface = 0;
posn->cylinder++;
}
}
}